"""
# fig4e.pdf
针对单个 app，绘制每个 service 上的 acc 随 load 的变化，一个 service 存一个 fig，所有 fig 存一个 PDF。

"""

import os
import pickle
import sys
import warnings

import matplotlib

matplotlib.use('Agg')  # 设置后端为 Agg

import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

warnings.filterwarnings("ignore")

pcolors = ['#000080', '#008000', '#990000', '#a5669f', '#db850d', '#00112d']
markers = ['s', 'o', 'x', '^', 'v', '*', 'p', 'h']
linestyle = ['-', '.', '--']

dir_path = os.path.dirname(os.path.realpath(__file__))
gs_font = fm.FontProperties(fname=dir_path + '/gillsans.ttf', size=20, weight='bold')
light_grey = (0.5, 0.5, 0.5)
matplotlib.rcParams['pdf.fonttype'] = 42
matplotlib.rcParams['ps.fonttype'] = 42

results_directory = sys.argv[1]
test_name_suffix = sys.argv[2]
output_file_name = sys.argv[3]
output_file_path = os.path.join(results_directory, output_file_name)
loads = [int(x) for x in sys.argv[4].split(",")]
app = sys.argv[5]

apdf = PdfPages(output_file_path)


def plot_lines(xs, ys, labels, xlabel, ylabel, svc_name):
    fig, ax = plt.subplots()
    nlines = len(xs)
    assert (len(ys) == nlines and len(labels) == nlines)
    for i in range(nlines):
        pcolor = pcolors[i]
        ax.plot(xs[i], ys[i], '-', color=pcolor, lw=2.5, marker=markers[i], mew=1.5, fillstyle="full", markersize=10,
                markeredgecolor=pcolor, dash_capstyle='round', label=labels[i], zorder=10, clip_on=False)

    label_fontsize = 20
    ax.set_xlabel(xlabel, fontproperties=gs_font, fontsize=label_fontsize)
    ax.set_ylabel(ylabel, fontproperties=gs_font, fontsize=label_fontsize)
    xmax = 1.05 * max([max(x) for x in xs])
    plt.ylim(ymin=0, ymax=100)
    plt.xlim(xmin=10, xmax=100)
    ax.grid(linestyle=':', linewidth=1, color='grey')
    ticklabelcolor = 'black'
    leg = ax.legend(loc="best", borderaxespad=0, numpoints=2, handlelength=2, prop=gs_font, fontsize=label_fontsize)
    leg.set_zorder(20)
    leg.get_frame().set_linewidth(0.0)
    plt.tick_params(labelsize=label_fontsize)
    axcolor = 'black'
    ax.xaxis.set_tick_params(width=2, length=10)
    ax.yaxis.set_tick_params(width=2, length=15)
    ax.xaxis.set_tick_params(which='both', colors=axcolor)
    ax.yaxis.set_tick_params(which='both', colors=axcolor)
    ax.spines['bottom'].set_color(axcolor)
    ax.spines['top'].set_color(axcolor)
    ax.spines['right'].set_color(axcolor)
    ax.spines['left'].set_color(axcolor)
    ticklabelcolor = 'black'
    ax.tick_params(axis='x', colors=ticklabelcolor, direction="in")
    ax.tick_params(axis='y', colors=ticklabelcolor, direction="in")

    for axis in ['top', 'bottom', 'left', 'right']:
        ax.spines[axis].set_color(light_grey)
    ax.spines['top'].set_linestyle(':')
    ax.spines['right'].set_linestyle(':')

    for label in ax.get_xticklabels():
        label.set_fontproperties(gs_font)
    for label in ax.get_yticklabels():
        label.set_fontproperties(gs_font)
    plt.tight_layout()
    ax.set_title(f"Accuracy vs load: '{svc_name}'")
    apdf.savefig(fig)


process_set = set()
# process => accuracy_load
# accuracy_load: method => load => acc
accuracy_load_per_process = {}
for i in range(len(loads)):
    with open(results_directory + "/process_acc_" + app + "_" + test_name_suffix + "_" + str(
            loads[i]) + "_1_1_0.0.pickle", 'rb') as afile:
        accuracy_per_process = pickle.load(afile)
        # 处理
        _accuracy_per_process = {}
        for (method, process), acc in accuracy_per_process.items():
            if method == "MaxScoreBatchSubsetWithSkips":
                method = "TraceWeaver"
            if type(process) == int:
                process = f"Process {process}"
            _accuracy_per_process[(method, process)] = acc
        accuracy_per_process = _accuracy_per_process
        # 导出
        for (method, process), acc in accuracy_per_process.items():
            process_set.add(process)
            if process not in accuracy_load_per_process:
                accuracy_load_per_process[process] = {}
            if method not in accuracy_load_per_process[process]:
                accuracy_load_per_process[process][method] = {}
            accuracy_load_per_process[process][method][loads[i]] = acc

# methods = ["TraceWeaver (Top K)", "TraceWeaver", "WAP5", "vPath", "FCFS"]
methods = ["TraceWeaver", "WAP5", "vPath", "FCFS"]
services = list(process_set)

for i in range(len(services)):
    xs = []
    ys = []
    for j in range(len(methods)):
        x = []
        y = []
        for k in range(len(loads)):
            x.append((loads[k] * 100) / 100)  # 替换成绝对度量
            try:
                acc = accuracy_load_per_process[services[i]][methods[j]][loads[k]]
                y.append(int(acc * 100))
            except KeyError:
                print(f"KeyError: service={services[i]}, method={methods[j]}, load={loads[k]}")
                y.append(0)
        xs.append(x)
        ys.append(y)
    plot_lines(xs, ys, methods, f"System load (RPS)", f"Span Accuracy %", services[i])

apdf.close()
